package com.jz.main.io.websocket;

import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Set;

public class NioLoop {
    private final Selector selector;

    public NioLoop() throws IOException {
        // 创建 Selector
        selector = Selector.open();
    }

    public void startServer(int port) throws IOException {
        // 打开 ServerSocketChannel，用于监听连接
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 绑定监听端口
        serverSocketChannel.bind(new InetSocketAddress(port));
        // 设置为非阻塞模式
        serverSocketChannel.configureBlocking(false);
        // 注册接受连接事件到 Selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        System.out.println("Server started on port " + port);

        // 事件循环
        while (true) {
            // 阻塞直到有事件发生
            selector.select();
            // 获取发生事件的 SelectionKey 集合
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                // 处理事件
                if (key.isAcceptable()) {
                    // 处理连接事件
                    acceptConnection(serverSocketChannel);
                }
                // 可以添加其他事件类型的处理，如读写事件等
            }
        }
    }

    private void acceptConnection(ServerSocketChannel serverSocketChannel) throws IOException {
        // 接受连接
        SocketChannel socketChannel = serverSocketChannel.accept();
        // 设置为非阻塞模式
        socketChannel.configureBlocking(false);
        // 注册读事件到 Selector
        socketChannel.register(selector, SelectionKey.OP_READ);
        System.out.println("Accepted connection from " + socketChannel.getRemoteAddress());
    }

    public static void main(String[] args) throws IOException {
        int port = 8081;
        NioLoop eventLoop = new NioLoop();
        eventLoop.startServer(port);
    }
}
